package com.yugao.fintech.antelope.infra.module.file.manager;

import com.yugao.fintech.antelope.base.config.core.ConfigFactory;
import com.yugao.fintech.antelope.base.model.enums.ConfigDefineEnum;
import com.yugao.fintech.antelope.base.model.enums.ConfigKeyEnum;
import com.yugao.fintech.antelope.base.model.module.config.ConfigInfo;
import com.yugao.fintech.antelope.base.model.module.config.param.BaseConfigParam;
import com.yugao.fintech.antelope.base.model.module.config.param.StorageParam;
import com.yugao.fintech.antelope.base.model.module.tenant.TenantContextHolder;
import com.yugao.fintech.framework.assistant.utils.UrlUtils;
import com.yugao.fintech.framework.assistant.utils.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
@Component
public class FileManager {
    /**
     * key: tenantId
     */
    public static final Map<String, StorageParam<?>> storageParamCache = new ConcurrentHashMap<>();

    /**
     * 添加 Lazy 避免循环引用
     */
    @Autowired
    @Lazy
    private ConfigFactory configFactory;


    /**
     * 获取虚拟url, 在网关会进行替换
     */
    public String getVirtualFileUrl(String objectName) {
        String tenantId = String.valueOf(TenantContextHolder.get().getTenantId());
        StorageParam<?> storageParam = storageParamCache.get(tenantId);
        if (Objects.isNull(storageParam)) {
            storageParam = (StorageParam<?>) createStorageParam();
        }
        if (Objects.isNull(storageParam)) {
            throw new BizException("尚未配置存储参数");
        }
        return UrlUtils.removeRepeatSlashOfUrl(String.format("http://%s.%s.file/%s", "1", storageParam.getBucket(), objectName));
    }

    public BaseConfigParam<?> createStorageParam() {
        ConfigInfo config = configFactory.getConfigOfNonNull(ConfigDefineEnum.STORAGE);
        String tenantId = String.valueOf(TenantContextHolder.get().getTenantId());
        BaseConfigParam<?> baseConfigParam;
        synchronized (tenantId.intern()) {
            baseConfigParam = storageParamCache.get(tenantId);
            if (Objects.nonNull(baseConfigParam)) {
                return baseConfigParam;
            }
            ConfigKeyEnum configKey = ConfigKeyEnum.ofAndCheck(config.getConfigKey());
            baseConfigParam = BaseConfigParam.jsonToObject(configKey, config.getConfigValue());
            storageParamCache.put(tenantId, (StorageParam<?>) baseConfigParam);
        }
        return baseConfigParam;
    }
}
